[图一] 是单元测试代码◦
[图二] 是产品代码◦
显而易见的是, 单元测试代码比产品代码还要多, 这合理吗?
当然合理!
产品代码虽然是只有短短的几行; 处理订阅者订阅赛马的消息◦
但, 却会衍生出许多不同的使用者场景; 如: 没有订阅者订阅, 只有单一或多个订阅者, 某个订阅者重复订阅, 某个订阅者取消订阅…..等等◦
单元测试, 根据这些不同的使用者场景, 分别有相对应的单元测试代码 (测试用例) ◦ 所以, 单元测试代码自然会比产品代码还要多◦
但, 这样的付出 (投资) 绝对是值得的◦
因为, 唯有如此所形成的 “自动化单元测试”, 才能使产品可在 “最短的时间内反馈”, 既有产品的架构, 功能与质量是否已被所新增的代码 (功能) 所破坏◦
所以, 我们应该真正专注的是, 单元测试的 “测试用例的有效性” , 而不是表面的单元测试代码的行数◦
package test.java.com;
import main.java.com.Client;
import main.java.com.Message;
import main.java.com.RaceResultsService;
import org.junit.Before;
import org.junit.Test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
/**
* Created by ScalaMind on 2015/3/3.
*/
public class RaceResultsServiceTest {
private RaceResultsServiceraceResults;
private Messagemessage;
private ClientclientA;
private ClientclientB;
@Before
public void setUp() {
raceResults = new RaceResultsService();
message = mock(Message.class);
clientA = mock(Client.class, "clientA");
clientB = mock(Client.class, "clientB");
}
// zero subscribers
@Test
public void notSubscribeClientShouldNotReceiveMessage() {
raceResults.send(message);
verify(clientA, never()).receive(message);
verify(clientB, never()).receive(message);
}
// one subscriber
@Test
public void subscribedClientShouldReceiveMessage() {
raceResults.addSubscriber(clientA);
raceResults.send(message);
verify(clientA).receive(message);
}
// two subscribers
@Test
public void messageShouldBeSentToAllSubscribedClients() {
RaceResultsService raceResults= new RaceResultsService();
Message message = mock(Message.class);
raceResults.addSubscriber(clientA);
raceResults.addSubscriber(clientB);
raceResults.send(message);
verify(clientA).receive(message);
verify(clientB).receive(message);
}
// subscribe more than once
@Test
public void shouldSendOnlyOneMessageToMultiSubscriber() {
raceResults.addSubscriber(clientA);
raceResults.addSubscriber(clientA);
raceResults.send(message);
verify(clientA).receive(message);
}
// remove a subscriber
@Test
public void unsubscribedClientShouldNotReceiveMessages() {
raceResults.addSubscriber(clientA);
raceResults.removeSubscriber(clientA);
raceResults.send(message);
verify(clientA, never()).receive(message);
}
}
[图一: 单元测试代码]
package main.java.com;
import java.util.Collection;
import java.util.HashSet;
/**
* Created by ScalaMind on 2015/3/3.
*/
public class RaceResultsService {
private Collection<Client> clients = new HashSet<Client>();
public void addSubscriber(Client client) {
clients.add(client);
}
public void send(Message message) {
for (Client client : clients)
client.receive(message);
}
public void removeSubscriber(Client client) {
clients.remove(client);
}
}
[图二: 产品代码]