gpt4 book ai didi

testing - 处理测试中的代码重复

转载 作者:行者123 更新时间:2023-11-28 21:05:28 25 4
gpt4 key购买 nike

在工作中,我尽可能多地实践测试驱动开发。我经常遇到的一件事是必须设置一堆 DTO,当它们的结构稍微复杂时,这就变成了很多代码。这样做的问题是代码通常很重复,我觉得它会分散测试的主要目的。例如,使用一个稍微做作和压缩的示例(在 java 中,jUnit + mockito):

class BookingServiceTest {

private final static int HOUR_IN_MILLIS = 60 * 60 * 1000;
private final static int LOCATION_ID = 1;
@Mock
private BookingLocationDao bookingLocationDao;

@InjectMocks
private BookingService service = new BookingService();

@Test
public void yieldsAWarningWhenABookingOverlapsAnotherInTheSameLocation() {
// This part is a bit repetetive over many tests:
Date now = new Date()
Location location = new Location()
location.setId(LOCATION_ID);

Booking existingBooking = new Booking()
existingBooking.setStart(now);
existingBooking.setDuration(HOUR_IN_MILLIS);
existingBooking.setLocation(location);
// To here

when(bookingLocationDao.findBookingsAtLocation(LOCATION_ID))
.thenReturn(Arrays.asList(existingBooking));

// Then again setting up a booking :\
Booking newBooking = new Booking();
newBooking.setStart(now);
newBooking.setDuration(HOUR_IN_MILLIS / 2);
newBooking.setLocation(location);


// Actual test...
BookingResult result = service.book(newBooking);

assertThat(result.getWarnings(), hasSize(1));
assertThat(result.getWarnings().get(0).getType(), is(BookingWarningType.OVERLAPING_BOOKING));
}

}

在这个例子中,设置并没有那么复杂,所以我不会考虑太多。然而,当需要更复杂的输入时,用于设置方法输入的代码往往会增加。在几个测试中使用类似的输入会加剧这个问题。将设置代码重构为单独的 TestUtil 类会有所帮助。那么问题是,在几个月后编写新测试时,很难找到这些实用程序类,从而导致重复。

  1. 处理这种“复杂”DTO 以最大限度地减少测试设置中的代码重复的好方法是什么?
  2. 您如何确保在使用类似代码时找到提取的 TestUtilities?
  3. 我做错了吗? :) 我是否应该以另一种方式构建我的软件以完全避免这种情况?如果是,怎么做?

最佳答案

有几种模式可以用来处理这种情况:

要深入讨论这些模式,请阅读优秀书籍 "Growing Object-oriented Software Guided by Tests"

测试数据生成器

为您希望促进实例化/设置的每个类创建一个构建器类。此类包含一系列方法,这些方法将正在构建的对象设置为特定状态。通常这些辅助方法会向构建器类返回一个实例,以便可以以流畅的方式链接调用。

// Example of a builder class:
public class InvoiceBuilder {
Recipient recipient = new RecipientBuilder().build();
InvoiceLines lines = new InvoiceLines(new InvoiceLineBuilder().build());
PoundsShillingsPence discount = PoundsShillingsPence.ZERO;

public InvoiceBuilder withRecipient(Recipient recipient) {
this.recipient = recipient;
return this;
}

public InvoiceBuilder withInvoiceLines(InvoiceLines lines) {
this.lines = lines;
return this;
}

public InvoiceBuilder withDiscount(PoundsShillingsPence discount) {
this.discount = discount;
return this;
}

public Invoice build() {
return new Invoice(recipient, lines, discount);
}
}

// Usage:
Invoice invoiceWithNoPostcode = new InvoiceBuilder()
.withRecipient(new RecipientBuilder()
.withAddress(new AddressBuilder()
.withNoPostcode()
.build())
.build())
.build();

对象母亲

对象母类是为不同的常见场景提供预制测试数据的类。

Invoice invoice = TestInvoices.newDeerstalkerAndCapeInvoice();

上面的例子是从 Nat Pryce's blog 借来的.

关于testing - 处理测试中的代码重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16356754/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com